#include "video.h"
#include <QDebug>
#include <QDateTime>
#include <QImage>

Video::Video(QObject *parent) : QObject(parent)
  ,myUdp(nullptr)
  ,udpPort(5688)
  ,showLab(nullptr)
{
    buffImg = new QImage(800,532,QImage::Format_RGB32);
   // qDebug()<<"img size:"<<buffImg->byteCount()<<"   img size:"<<buffImg->size()<<"   img format:"<<buffImg->format();
    myUdp = new QUdpSocket(this);
    setUdpPort(udpPort);
    connect(myUdp, SIGNAL(readyRead()), this, SLOT(onUdpReceive()));
}

QByteArray imgByteBuff;
void Video::onUdpReceive()
{
    while(myUdp->hasPendingDatagrams())
    {
        QByteArray buffData;
        buffData.resize(myUdp->pendingDatagramSize());
        myUdp->readDatagram(buffData.data(), buffData.size());
        imgByteBuff.append(buffData);
    }
    if(paraImg(imgByteBuff,buffImg))
    {
        qDebug()<<"receive img!";
        if(showLab != nullptr && !buffImg->isNull())
        {
            buffImg->scaled(showLab->size(), Qt::KeepAspectRatio);
            showLab->setPixmap(QPixmap::fromImage(*buffImg));
        }
    }
}

bool Video::paraImg(QByteArray &datagram,QImage *myImg)
{
    if(datagram.size() < sizeof(PackageHeader))
        return false;
    PackageHeader *packageHead = (PackageHeader *)datagram.data();
    qDebug()<<"receive data size:"<<datagram.size()<<"img size:"<<packageHead->dataSize;
    datagram = datagram.mid(packageHead->packSize+packageHead->dataSize);
//    if(currentImgId != packageHead->imgID)
//        receivingImg.resize(packageHead->imgSize);

//    if (packageHead->dataOffset > packageHead->imgSize - packageHead->dataSize)
//        packageHead->dataOffset = packageHead->imgSize - packageHead->dataSize;
//    if (packageHead->dataSize > packageHead->frameDataLen)
//        packageHead->dataSize = packageHead->frameDataLen;
    if((packageHead->dataOffset + packageHead->dataSize) <= myImg->byteCount())
        memcpy(myImg->bits() + packageHead->dataOffset,
               datagram.data() + packageHead->packSize, packageHead->dataSize);
//    memcpy(receivingImg.data() + packageHead->dataOffset,
//           datagram.data() + packageHead->packSize, packageHead->dataSize);
    //if((packageHead->dataOffset + packageHead->dataSize) >= packageHead->imgSize)   //数据接收完毕
    if(packageHead->currentFrameNum >= packageHead->frameNum)
    {
        //myImg->loadFromData(receivingImg,"jpg");
        //receivingImg.clear();
        return true;
    }
    return false;
}

#include <unistd.h>
#define UDP_MAX_SIZE 10000
void Video::imgSend(QImage *myImg,QUdpSocket *udp,QString strIP,quint16 port)
{
    static uint imgCount = 0;
    uint imgLength = myImg->byteCount();
    if(imgLength == 0) return ;

    unsigned char *imgBuffer = myImg->bits();

    PackageHeader udpPack;
    uint packetNum = imgLength / UDP_MAX_SIZE;
    uint lastPaketSize = imgLength % UDP_MAX_SIZE;
    if (lastPaketSize != 0)
        packetNum ++;

    udpPack.imgID = imgCount ++;
    udpPack.packSize = sizeof(PackageHeader);
    udpPack.imgSize = imgLength;
    udpPack.frameDataLen = UDP_MAX_SIZE;
    udpPack.frameNum = packetNum;

    quint32 dataOffset = 0;
    unsigned char frameBuffer[UDP_MAX_SIZE + 128];
    for(uint i = 0;i < packetNum;i ++)
    {
        udpPack.currentFrameNum = i + 1;
        if(udpPack.currentFrameNum == packetNum)
            udpPack.dataSize = lastPaketSize;
        else
            udpPack.dataSize = UDP_MAX_SIZE;
        udpPack.dataOffset = dataOffset;

        memcpy(frameBuffer,&udpPack, udpPack.packSize);
        memcpy(frameBuffer + udpPack.packSize, imgBuffer + dataOffset, udpPack.dataSize);
        udp->writeDatagram((char *)frameBuffer, udpPack.packSize + udpPack.dataSize,
                           QHostAddress(strIP),port);
        udp->waitForBytesWritten();
        qDebug()<<"img data offset:"<<dataOffset<<"   send data size:"<<udpPack.dataSize;
        dataOffset += udpPack.dataSize;
    }
}

void Video::Delay(int msec)
{
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}


